﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlServerCe;
using System.Diagnostics;

namespace Flare.DB
{
    class endpoints_map
    {
        public List<Entity.EndpointMap> Index()
        {

            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
            {
                using (SqlCeCommand command = new SqlCeCommand(
                        @"SELECT [id],[dev_name],[dev_type],[dev_ip],[pointA_X],[pointB_Y] FROM [endpoints_map]", connection))
                {
                    try
                    {
                        connection.Open();
                    }
                    catch (Exception ex)
                    {
                        glob.kernel.Panic(glob.PanicType.db_connect, ex);
                    }
                    var endpoint = new List<Entity.EndpointMap>();
                    try
                    {
                        using (SqlCeDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                var current_entity = new Entity.EndpointMap();
                                current_entity.id = (reader["id"].GetType() == typeof(System.DBNull)) ? null : (int?)Convert.ToInt32(reader["id"]);
                                current_entity.dev_name = (reader["dev_name"].GetType() == typeof(System.DBNull)) ? null : reader["dev_name"].ToString();
                                current_entity.dev_type = (Flare.Controls.NetworkPointType)Enum.Parse(typeof(Flare.Controls.NetworkPointType), reader["dev_type"].ToString(), true);
                                current_entity.dev_ip = (reader["dev_ip"].GetType() == typeof(System.DBNull)) ? null : reader["dev_ip"].ToString();
                                current_entity.pointA_X = Convert.ToDouble(reader["pointA_X"]);
                                current_entity.pointB_Y = Convert.ToDouble(reader["pointB_Y"]);
                                endpoint.Add(current_entity);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(command.CommandText);
                        glob.kernel.Panic(glob.PanicType.sql, ex);
                    }
                    return endpoint;
                }
            }
        }

        public int? Create(Entity.EndpointMap data)
        {
            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
            {
                using (SqlCeCommand command = new SqlCeCommand(@"INSERT INTO [endpoints_map] ([dev_name],[dev_type],[dev_ip],[pointA_X],[pointB_Y]) OUTPUT INSERTED.ID
                                                             VALUES (@dev_name, @dev_type, @dev_ip, @pointA_X, @pointB_Y)", connection))
                {
                    command.Parameters.Add("@dev_name", SqlDbType.VarChar).Value = (object)data.dev_name ?? DBNull.Value;
                    command.Parameters.Add("@dev_type", SqlDbType.VarChar).Value = data.dev_type;
                    command.Parameters.Add("@dev_ip", SqlDbType.VarChar).Value = (object)data.dev_ip ?? DBNull.Value;
                    command.Parameters.Add("@pointA_X", SqlDbType.Float).Value = (object)data.pointA_X ?? DBNull.Value;
                    command.Parameters.Add("@pointB_Y", SqlDbType.Float).Value = (object)data.pointB_Y ?? DBNull.Value;
                    try
                    {
                        connection.Open();
                    }
                    catch (Exception ex)
                    {
                        glob.kernel.Panic(glob.PanicType.db_connect, ex);
                    }

                    try
                    {
                        return (int)command.ExecuteScalar();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(command.CommandText + "\n" + ex.Message);
                        throw new Exception("Во время добавления данных произошла ошибка. Данные не сохранены");
                    }
                }
            }
        }

        public void Edit(Entity.EndpointMap data)
        {
            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
            {
                using (SqlCeCommand command = new SqlCeCommand(@"UPDATE [endpoints_map] SET [dev_name] = @dev_name,[dev_type] = @dev_type,
                                                           [dev_ip] = @dev_ip,[pointA_X] = @pointA_X,[pointB_Y] = @pointB_Y WHERE [id] = @id", connection))
                {
                    command.Parameters.Add("@id", SqlDbType.Int).Value = (object)data.id ?? DBNull.Value;
                    command.Parameters.Add("@dev_name", SqlDbType.VarChar).Value = (object)data.dev_name ?? DBNull.Value;
                    command.Parameters.Add("@dev_type", SqlDbType.VarChar).Value = data.dev_type;
                    command.Parameters.Add("@dev_ip", SqlDbType.VarChar).Value = (object)data.dev_ip ?? DBNull.Value;
                    command.Parameters.Add("@pointA_X", SqlDbType.Float).Value = (object)data.pointA_X ?? DBNull.Value;
                    command.Parameters.Add("@pointB_Y", SqlDbType.Float).Value = (object)data.pointB_Y ?? DBNull.Value;

                    try
                    {
                        connection.Open();
                    }
                    catch (Exception ex)
                    {
                        glob.kernel.Panic(glob.PanicType.db_connect, ex);
                    }

                    try
                    {
                        command.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(command.CommandText + "\n" + ex.Message);
                        throw new Exception("Во время обновления данных произошла ошибка. Данные не сохранены");
                    }
                }
            }
        }

        //        public void Delete(int id)
        //        {
        //            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
        //            {
        //                try
        //                {
        //                    new MyService().TestConnect(connection.DataSource);
        //                    connection.Open();
        //                }
        //                catch
        //                {
        //                    glob.application_stop = FaultedType.sql;
        //                    return;
        //                }

        //                using (SqlCeCommand command = new SqlCeCommand(@"DELETE FROM [endpoints] WHERE [id_endpoint]=@id_endpoint", connection))
        //                {
        //                    command.Parameters.Add("@id_endpoint", SqlDbType.Int).Value = id;

        //                    try
        //                    {
        //                        command.ExecuteNonQuery();
        //                    }
        //                    catch (Exception ex)
        //                    {
        //                        MyService.SendStackByMail(command.CommandText + "\n" + ex.Message + "\n" + ex.StackTrace);
        //                        throw new Exception("Во время добавления данных произошла ошибка. Данные не сохранены");
        //                    }
        //                }
        //            }
        //        }

        public List<Entity.EndpointMapGenerate> MapGenerate()
        {
            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
            {
                try
                {
                    connection.Open();
                }
                catch (Exception ex)
                {
                    glob.kernel.Panic(glob.PanicType.db_connect, ex);
                }

                var tmp_ep_maps = new List<string>();
                using (SqlCeCommand command = new SqlCeCommand(@"SELECT [dev_ip] FROM [endpoints_map]", connection))
                {
                    try
                    {
                        using (SqlCeDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                tmp_ep_maps.Add(reader["dev_ip"].ToString());
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(command.CommandText);
                        glob.kernel.Panic(glob.PanicType.sql, ex);
                    }
                }

                var ep_maps = new List<Entity.EndpointMapGenerate>();
                using (SqlCeCommand command = new SqlCeCommand(@"SELECT [name],[id_type],[net_ip],[id_department] FROM [view_endpoints] 
                                                             WHERE [check_connect]=1 OR [id_type]=2 OR [id_type]=4", connection))
                {
                    using (SqlCeDataReader reader = command.ExecuteReader())
                    {
                        try
                        {
                            while (reader.Read())
                            {
                                if (tmp_ep_maps.Contains(reader["net_ip"].ToString())) continue;
                                var current_endpoint = new Entity.EndpointMapGenerate();
                                current_endpoint.name = reader["name"].ToString();
                                current_endpoint.net_ip = reader["net_ip"].ToString();
                                current_endpoint.id_type = Convert.ToInt32(reader["id_type"]);
                                ep_maps.Add(current_endpoint);
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(command.CommandText);
                            glob.kernel.Panic(glob.PanicType.sql, ex);
                        }
                    }
                }
                return ep_maps;
            }
        }

        public List<Entity.EndpointCheckHistory> HistoryCheck(string IP)
        {
            using (SqlCeConnection connection = new SqlCeConnection(glob.DBConnection))
            {
                using (SqlCeCommand command = new SqlCeCommand(string.Format("SELECT [check_time],[check_delay] FROM [check_log] WHERE [ip] LIKE '{0}' ORDER BY [check_time] DESC", IP), connection))
                {
                    try
                    {
                        connection.Open();
                    }
                    catch (Exception ex)
                    {
                        glob.kernel.Panic(glob.PanicType.db_connect, ex);
                    }

                    var ep_check = new List<Entity.EndpointCheckHistory>();
                    try
                    {
                        using (SqlCeDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                Entity.EndpointCheckHistory current_check = new Entity.EndpointCheckHistory();
                                if (reader["check_delay"].GetType() != typeof(DBNull))
                                {
                                    double d = (Convert.ToDouble(reader["check_delay"]) < 3) ? 3 : Convert.ToDouble(reader["check_delay"]);
                                    current_check.check_delay = Convert.ToDouble(reader["check_delay"]);
                                    current_check.check_graph_h = Math.Log(d, 3) * 10;
                                }
                                else
                                {
                                    current_check.check_delay = null;
                                    current_check.check_graph_h = 5;
                                }

                                current_check.check_time = Convert.ToDateTime(reader["check_time"]);
                                ep_check.Add(current_check);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(command.CommandText);
                        glob.kernel.Panic(glob.PanicType.sql, ex);
                    }
                    return ep_check;
                }
            }
        }
    }
}
